package com.xbongbong.saas.help.fund;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormSubDataEntity;
import com.xbongbong.paas.elasticsearch.model.PaasFormSubDataEsModel;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.PayPlanSubDataEntity;
import com.xbongbong.saas.model.PayPlanModel;
import com.xbongbong.saas.model.PayPlanSubDataModel;
import org.elasticsearch.action.support.WriteRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author 吴峰
 * @date 2020/10/15 14:39
 */
@Component
public class PayPlanHelp {

    private static final Logger LOGGER = LoggerFactory.getLogger(PayPlanHelp.class);

    @Resource
    private PayPlanModel payPlanModel;
    @Resource
    private PayPlanSubDataModel payPlanSubDataModel;
    @Resource
    private PaasFormSubDataEsModel paasFormSubDataEsModel;

    public void updateBatch(List<? extends PaasFormDataEntity> payPlanList, String corpid, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        if (CollectionsUtil.isEmpty(payPlanList)) {
            return;
        }
        Set<String> subAttrSet = new HashSet<>();
        explainMap.forEach((item, value)->{
            if (Objects.equals(FieldTypeEnum.SUB_FORM.getType(), value.getFieldType())) {
                subAttrSet.add(item);
            }
        });
        List<PayPlanSubDataEntity> sourcePayPlanSubDataList = new ArrayList<>();
        List<PayPlanSubDataEntity> updatePayPlanSubDataList = new ArrayList<>();
        List<PayPlanSubDataEntity> insertPayPlanSubDataList = new ArrayList<>();
        Map<Long, Long> payPlanSubDataIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        try {
            payPlanModel.updateBatchForData(payPlanList, corpid);
            if (CollectionsUtil.isNotEmpty(subAttrSet)) {

                Set<Long> parentIdList = new HashSet<>();
                Map<Long, Long> subDataIdList = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                long now = DateTimeUtil.getInt();
                payPlanList.forEach(item->{
                    parentIdList.add(item.getId());
                    JSONObject subFormData = item.getSubFormData();
                    subAttrSet.forEach(attr->{
                        JSONArray jsonArray = subFormData.getJSONArray(attr);
                        if (Objects.nonNull(jsonArray)) {
                            for (int i = 0; i < jsonArray.size(); i++) {
                                JSONObject jsonObject = jsonArray.getJSONObject(i);
                                Long subDataId = jsonObject.getLong(BusinessConstant.SUB_DATA_ID);
                                if (Objects.isNull(subDataId)) {
                                    PayPlanSubDataEntity paymentSubDataEntity = new PayPlanSubDataEntity(item.getFormId(), corpid, item.getId(), attr, jsonObject);
                                    insertPayPlanSubDataList.add(paymentSubDataEntity);
                                } else {
                                    subDataIdList.put(subDataId, item.getId());
                                    PayPlanSubDataEntity payPlanSubDataEntity = new PayPlanSubDataEntity();
                                    jsonObject.remove(BusinessConstant.SUB_DATA_ID);
                                    payPlanSubDataEntity.setCorpid(corpid);
                                    payPlanSubDataEntity.setId(subDataId);
                                    payPlanSubDataEntity.setData(jsonObject);
                                    payPlanSubDataEntity.setDataId(item.getDataId());
                                    payPlanSubDataEntity.setUpdateTime(now);
                                    payPlanSubDataEntity.setDel(DelEnum.NORMAL.getDel());
                                    updatePayPlanSubDataList.add(payPlanSubDataEntity);
                                }
                            }
                        }
                    });
                });
                if (CollectionsUtil.isNotEmpty(parentIdList)) {
                    Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put(StringConstant.CORPID, corpid);
                    param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                    param.put("dataIdIn", parentIdList);
                    List<? extends PaasFormSubDataEntity> payPlanSubDataList = payPlanSubDataModel.findEntitys(param);
                    if (Objects.nonNull(payPlanSubDataList)) {

                        for (PaasFormSubDataEntity item : payPlanSubDataList) {
                            if (!subDataIdList.containsKey(item.getId())) {
                                // 前端传来的数据中已经没有了这个id，说明该行子表单数据已被删除
                                payPlanSubDataIdMap.put(item.getId(), item.getDataId());
                            }
                        }
                        if (!payPlanSubDataIdMap.isEmpty()) {
                            payPlanSubDataModel.deleteBatchByIdIn(payPlanSubDataIdMap, corpid);
                        }
                    }
                }
                if (CollectionsUtil.isNotEmpty(insertPayPlanSubDataList)) {

                    payPlanSubDataModel.insertBatch(insertPayPlanSubDataList);
                }
                if (CollectionsUtil.isNotEmpty(updatePayPlanSubDataList)) {
                    Set<Long> paymentSheetIdList = new HashSet<>();
                    updatePayPlanSubDataList.forEach(item->{
                        paymentSheetIdList.add(item.getId());
                    });
                    Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put(StringConstant.CORPID, corpid);
                    param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                    param.put(StringConstant.IDIN, paymentSheetIdList);
                    sourcePayPlanSubDataList = payPlanSubDataModel.findEntitys(param);
                    // 更新
                    payPlanSubDataModel.updateBatchByEntity(updatePayPlanSubDataList, corpid);
                }
            }
        } catch (Exception e) {
            LOGGER.error("payPlanHelp.updateBatch批量保存付款计划出错：", e);
            // 回滚
            rollback(sourcePayPlanSubDataList, insertPayPlanSubDataList, payPlanSubDataIdMap, corpid);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    private void rollback(List<PayPlanSubDataEntity> sourcePayPlanSubDataList, List<PayPlanSubDataEntity> insertPaymentSheetSubDataList,
                          Map<Long, Long> payPlanSheetSubDataIdMap, String corpid) {
        try {
            if (CollectionsUtil.isNotEmpty(sourcePayPlanSubDataList)) {
                paasFormSubDataEsModel.updateBatchByEntity(sourcePayPlanSubDataList, IndexTypeEnum.IDX_SAAS_PAY_PLAN_SUB, WriteRequest.RefreshPolicy.NONE);
            }
            if (CollectionsUtil.isNotEmpty(insertPaymentSheetSubDataList)) {
                Map<Long, Long> idMap = new HashMap<>(insertPaymentSheetSubDataList.size());
                insertPaymentSheetSubDataList.forEach(item->{
                    idMap.put(item.getId(), item.getDataId());
                });
                paasFormSubDataEsModel.deleteBatchByIdIn(corpid, idMap, IndexTypeEnum.IDX_SAAS_PAY_PLAN_SUB, WriteRequest.RefreshPolicy.NONE, DelEnum.DELETE);
            }
            if (!payPlanSheetSubDataIdMap.isEmpty()) {
                paasFormSubDataEsModel.deleteBatchByIdIn(corpid, payPlanSheetSubDataIdMap, IndexTypeEnum.IDX_SAAS_PAY_PLAN_SUB, WriteRequest.RefreshPolicy.NONE, DelEnum.NORMAL);
            }
        } catch (Exception e) {
            LOGGER.error("payPlanSheetHelp.rollback回滚失败：", e);
        }

    }
}
